/*
 * graph2D
 * Copyright (c) 2009 Shun Moriya <shun@mnu.sakura.ne.jp>
 *
 * The MIT License
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#if !defined(___GRAPHC2D_MENU_H___)
#define ___GRAPHC2D_MENU_H___

#if !defined(___GRAPH2D_IMAGE_BUTTON_H___)
#include "imageButton.h"
#endif

#if !defined(___GRAPH2D_STATIC_CONTAINER_H___)
#include "staticContainer.h"
#endif

#if !defined(___GRAPHC2D_TEXT_H___)
#include "text.h"
#endif

#if !defined(___GRAPH2D_VARIABLE_CONTAINER_H___)
#include "variableContainer.h"
#endif

#if !defined(___GRAPH2D_WINDOW_H___)
#include "window.h"
#endif

namespace Graph2D
{
	class Button;
	class VariableContainer;

	//! @brief レイヤー番号
	enum Layer
	{
		MENU_LAYER_CLOSE_BUTTON = 0,
		MENU_LAYER_CAPTION,
		MENU_LAYER_CONTAINER,
		MENU_LAYER_SIZE
	};

	typedef StaticContainer<MENU_LAYER_SIZE> MenuWindowContainer;

	/*!
	 * @brief メニュークラス<br/>
	 * コンポーネントを整列するレイアウト機能が入ったユーティリティクラスです
	 */
	class Menu : public Window<MenuWindowContainer>, public ActionEvent, public ClickEvent
	{
		DISALLOW_COPY_AND_ASSIGN(Menu);

		//! @brief 親クラス型
		typedef Window<MenuWindowContainer> super;

	public:
		//! @brief コンストラクタ
		Menu();

		//! @brief デストラクタ
		virtual ~Menu();

		/*!
		 * @brief	タイプ名を取得
		 * @return	タイプ名
		 */
		virtual const char* getTypeName() const
		{
			return "Menu";
		}

		////////////////////////////////////////////////////////////////////////////////////////////
		/*!
		 * @brief	キャプション(Text)オブジェクトを取得します
		 * @return	キャプション(Text)オブジェクト
		 */
		Text* getCaption()
		{
			return &caption;
		}

		/*!
		 * @brief		キャプションを設定
		 * @param[in]	caption	キャプション
		 */
		void setCaption(const std::string& caption)
		{
			this->caption.setString(caption);
		}

		////////////////////////////////////////////////////////////////////////////////////////////
		//! @brief 閉じるボタンを取得
		ImageButton* getCloseButton();
		//! @brief 閉じるボタンを設定
		void setCloseButton(ImageButton* button);

		////////////////////////////////////////////////////////////////////////////////////////////
		//! @brief コンテナーを取得
		VariableContainer* getContainer();
		//! @brief コンテナーを設定
		void setContainer(VariableContainer* container);

		//! @brief コンテナーにコンテンツを追加
		void addContents(Component* component, const int data);
		//! @brief コンテナーにコンテンツを追加
		Button* addContents(const std::string& text, const int data);
		//! @brief コンテナー内のコンテンツを検索
		Component* searchContents(const unsigned int data);
		//! @brief コンテナー内のコンテンツをクリア
		void clearContents();

		//! @brief パディングサイズを取得
		unsigned short getPadding() const;
		//! @brief パディングサイズを設定
		void setPadding(const unsigned short padding);

		//! @brief コンテナー内のコンテンツの位置やサイズを調整
		void adjust();

		////////////////////////////////////////////////////////////////////////////////////////////
		//! @brief シリアライズイベント
		virtual void onSerialize(mana_stream* stream) const;
		//! @brief デシリアライズイベント
		virtual void onDeserialize(mana_stream* stream);
#if defined(DEBUG) || defined(_DEBUG) || defined(_DEBUG_) || !defined(NDEBUG)
		//! @brief 更新イベント
		virtual void onUpdate(const UpdateInfomation& updateInfomation)
		{
			super::onUpdate(updateInfomation);
		}
#endif
		//! @brief 描画イベント
		virtual bool onDraw(const DrawRect& drawRect);
		//! @brief アクションイベント
		virtual void onAction(Component* component, const unsigned int identification);
		//! @brief クリックイベント
		virtual void onClick(Component* component);
		//! @brief クローズボタンが押されたイベント
		virtual void onCloseButtonDown();

		////////////////////////////////////////////////////////////////////////////////////////////
		//! @brief 同じメニューか比較
		virtual bool compare(const Menu& other) const;

	private:
		Text caption;					//!< キャプション
		VariableContainer container;	//!< 可変長コンテナ
		unsigned short paddingSize;		//!< パディングサイズ
		bool dirty;						//!< 変更ありフラグ
	};
}

#endif
